import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ConnectionManager {

	protected Socket sock = null;
	public int PORT = 5090;
	private boolean isOpen = false;
	
	public ConnectionManager(int port) {
		this.PORT = port;
	}
	
	public ConnectionManager(Socket s){
		this.sock = s;
		this.PORT = s.getLocalPort();
		this.isOpen = true;
	}
	
	public Socket connectTo(IMachine dest)
	{
		//create the socket and and connect to the dest
		try {
			sock = new Socket(dest.getIP(),PORT);
			isOpen = true;
		} 
		catch (UnknownHostException e) 
		{
			e.printStackTrace();
		}
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		return sock;
		
	}
	
	public Socket connectTo(IMachine dest,int destport)
	{
		//create the socket and and connect to the dest
		try {
			sock = new Socket(dest.getIP(),destport);
			isOpen = true;
		} 
		catch (UnknownHostException e) 
		{
			e.printStackTrace();
		}
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		return sock;
		
	}
	public void disconnectFrom(IMachine dest)
	{
		if(!isOpen)
			return;
		try {
			sock.close();
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		isOpen = false;
	}
	public int writeData(IMachine dest,byte[] data)
	{
		try{
			OutputStream os = sock.getOutputStream();
			//ObjectOutputStream oos = new ObjectOutputStream(sock.getOutputStream());
			//System.out.println("writing " + data.length + " bytes of data to machine " + sock.getInetAddress().getHostAddress() + " and port : " + sock.getPort());
			//System.out.println("bytes of length : ");
			//printByteArray(Message.getBytesForInt(data.length));
			os.write(Message.getBytesForInt(data.length));			
			os.write(data);
			os.flush();
			//System.out.println("data sent");
		}
		catch(IOException ioe)
		{
			ioe.printStackTrace();			
		}		
		return 0;
	}
	
	public void printByteArray(byte[] x)
	{
		for(int i = 0;i < x.length;i++)
			System.out.print(x[i] + ",");		
	}
	public IMessage receiveMessage() throws IOException
	{
		IMessage message = new Message();
		//System.out.println("inside receive message");
		InputStream is = sock.getInputStream();
		//ObjectInputStream ois = new ObjectInputStream(sock.getInputStream());
		byte[] intarray = new byte[4];
		int readTillNow = 0;
		while(readTillNow < 4){
			readTillNow += is.read(intarray, readTillNow, intarray.length - readTillNow); 
		}
		readTillNow = 0;
		int len = Message.getIntForBytes(intarray);
		//System.out.println("data length " + len + " receieved from machine " + sock.getRemoteSocketAddress().toString() + " and port : " + sock.getLocalPort());
		//System.out.println("bytes of length : ");
		//printByteArray(intarray);
		byte[] data = new byte[len];
		while(readTillNow < len){
			readTillNow += is.read(data, readTillNow, len - readTillNow); 
		}		
		//System.out.println("got data " + data);
		message.deserialize(data);
		
		//System.out.println("after desrializing " + message);
		return message;
	}
}
